﻿# More info at http://psautodeploy.codeplex.com
# Author: SPFernando

Import-Module .\Utils.ps1

# Install Solution (GAC or Global Resources across all Web Applications)
function InstallSolution
{
	param(
		[parameter(Position=0, Mandatory=$true)]
		$SolutionToInstall,
		[parameter(Position=1, Mandatory=$true)]
		[string]$Url,
		[parameter(Position=2, Mandatory=$false)]
		[bool]$Auto=$false
	)
	if ($SolutionToInstall.ContainsWebApplicationResource) {		
		Install-SPSolution -Identity $SolutionToInstall -AllWebApplications -GacDeployment:$SolutionToInstall.ContainsGlobalAssembly -Force | Out-Null	
	}
	else {
		if ($Auto -eq $false) {
			$AllWebApps = YesNo "Do you want deploy this solution across All Web Applications?" "This solutions no needs deployed globally but you could force."
			if ($AllWebApps) {
				Install-SPSolution -Identity $SolutionToInstall -AllWebApplications -GacDeployment:$SolutionToInstall.ContainsGlobalAssembly -Force | Out-Null
			}
			else {
				if ($SolutionToInstall.ContainsGlobalAssembly) {
				Install-SPSolution -Identity $SolutionToInstall -GacDeployment -Force | Out-Null
				}
				else {
					Install-SPSolution -Identity $SolutionToInstall -WebApplication $Url -Force | Out-Null
				}
			}
		}
		else {
			if ($SolutionToInstall.ContainsGlobalAssembly) {
				Install-SPSolution -Identity $SolutionToInstall -GacDeployment -Force | Out-Null
			}
			else {
				Install-SPSolution -Identity $SolutionToInstall -WebApplication $Url -Force | Out-Null
			}
		}
	}	
}

# Add Solution To Farm
function AddSolution {
	param(
		[parameter(Position=0, Mandatory=$true)]
		[string]$SolutionPath, 
		[parameter(Position=1, Mandatory=$true)]
		[string]$SolutionName,
		[parameter(Position=2, Mandatory=$false)]
		[string]$Url,
		[parameter(Position=3, Mandatory=$false)]
		[bool]$Auto=$false
	) 

	try {
		$ErrorActionPreference = 'Stop'
		Write-Host "`nAdding solution: " $SolutionName -ForegroundColor "DarkGreen"
		LogWrite "TRACE - Adding Solution $SolutionName"

		Add-SPSolution -LiteralPath $SolutionPath | Out-Null
		$SolutionToCheck = Get-SPSolution -Identity $SolutionName

		Write-Host "`nSolution deployment step: " $SolutionName -ForegroundColor "DarkGreen"	
		LogWrite "TRACE - Installing Solution $SolutionName"

		if ($SolutionToCheck) {
			InstallSolution $SolutionToCheck $Url $Auto
		}
		
		LogWrite "TRACE - Waiting until Timer Job operation is ended"
		
		$TimeOut = 0
				
		while ($SolutionToCheck.JobExists -or $SolutionToCheck.Deployed -eq $false -and $TimeOut -lt 10) {
			Waiting 7 $TimeOut
			$TimeOut = $TimeOut + 1
		}		
		
		if ($TimeOut -eq 10) {			
			LogWrite "ERROR - AddSolution - Time Out"
			throw (New-Object System.TimeoutException)
		}
		
		LogWrite "TRACE - Installed Solution $SolutionToInstall"
	}
	catch {
		# Show & Log Error
		LogWrite "ERROR - AddSolution - $_.Exception.Message"
		Write-Error "`n$_.Exception.Message." 		
		KeyDown
	}
}

# Remove Solution
function RemoveSolution {
	param(
		[parameter(Position=0, Mandatory=$true)]
		$SolutionToRemove, 
		[parameter(Position=1, Mandatory=$true)]
		[string]$SolutionName
	)

	$ErrorActionPreference = "Stop"
	Write-Host "`nRemoving solution: " $SolutionName -ForegroundColor "DarkGreen"	
	LogWrite "TRACE - Removing Solution $SolutionName"
	Remove-SPSolution $SolutionToRemove -Confirm:$false		
	LogWrite "TRACE - Removed Solution $SolutionName"		
}

# Uninstall Solution To Farm
function UninstallSolution {
	param(
		[parameter(Position=0, Mandatory=$true)]
		[string]$SolutionName,
		[parameter(Position=1, Mandatory=$true)]
		[string]$Url
	)  
	try {
		$ErrorActionPreference = 'Stop'
		Write-Host "`nUninstalling solution: " $SolutionName -ForegroundColor "DarkGreen"
		LogWrite "TRACE - Uninstalling Solution $SolutionName"
		
		$SolutionToCheck = Get-SPSolution -Identity $SolutionName
		
		if ($SolutionToCheck.ContainsWebApplicationResource) {
			Uninstall-SPSolution -Identity $SolutionToCheck -WebApplication $Url -Confirm:$false		
		}
		else {
			Uninstall-SPSolution -Identity $SolutionToCheck -AllWebApplications -Confirm:$false				
		}
		
		while ($SolutionToCheck.JobExists -or $SolutionToCheck.Deployed) {
			Waiting 10		
		}	
		
		RemoveSolution $SolutionToCheck $SolutionName 
	}
	catch {
		# Show & Log Error
		LogWrite "ERROR - UninstallSolution - $_.Exception.Message"
		Write-Error "`n$_.Exception.Message." 		
		KeyDown
	}		
}

# Update Solution (if exists but not deployed, uninstall and add renew)
function UpdateSolution {
	param(
		[parameter(Position=0, Mandatory=$true)]
		[string]$SolutionPath, 
		[parameter(Position=1, Mandatory=$true)]
		[string]$SolutionName,
		[parameter(Position=2, Mandatory=$true)]
		[string]$Url,
		[parameter(Position=3, Mandatory=$false)]
		[bool]$Auto=$false
	) 

	try {
		$ErrorActionPreference = 'Stop'
		Write-Host "`nSolution already exists, re-deployment step" -ForegroundColor "Yellow"
	    LogWrite "TRACE - Updating Solution $SolutionName"
		$ExistingSolution = Get-SPSolution -Identity $SolutionName
		
		if ($ExistingSolution.Deployed) {
			Update-SPSolution -Identity $SolutionName -LiteralPath $SolutionPath -GACDeployment -Force | Out-Null
		}
		else {
			RemoveSolution $ExistingSolution $SolutionName
			AddSolution $SolutionPath $SolutionName $Url $Auto
		}
		LogWrite "TRACE - Updated Solution $SolutionName"
	}
	catch {
		# Show & Log Error
		LogWrite "ERROR - UpdateSolution - $_.Exception.Message"
		Write-Error "`n$_.Exception.Message." 		
		KeyDown
	}	
}
